var express = require('express');
var jwt = require('jsonwebtoken');
var router = express.Router();
const bcrypt = require('bcrypt');
const nodemailer = require('nodemailer');
var axios = require('axios');
var {
    User,
    Role,
    Permission,
    UserRole,
    RolePermission,
    VerificationCode
} = require('../model/model');
const OpenApi = require('@alicloud/openapi-client');
const AFS = require('@alicloud/afs20180112');
const SMSClient = require('@alicloud/sms-sdk');
function generateVerificationCode() {
    return Math.floor(100000 + Math.random() * 900000).toString();
}
// Gitee OAuth配置
const GITEE_CLIENT_ID = '7820b72962b33bf9fcab4aede83dc7ab5126bb27803e3aba1a897f46a76a0adb';
const GITEE_CLIENT_SECRET = '4c93bc3741f012b668e9110cb3b5e8dc79904bcd4979bf34a9ccd0f766fd73df';
const GITEE_REDIRECT_URI = 'http://localhost:5173/callback';

const createAFSClient = () => {
    const config = new OpenApi.Config({
        accessKeyId: "LTAI5tGvYcwsi9seeFzW3UVY",
        accessKeySecret: "dXVDsN8HZWfZfTiMqvoIpu4zGWnpTm",
    });
    config.endpoint = `afs.aliyuncs.com`;
    return new AFS.default(config);
};

// 生成随机状态参数
const generateState = () => {
    return Math.random().toString(36).substring(2, 15);
};
// 登录 生成双token
// Gitee登录路由
router.get('/gitee/auth', (req, res) => {
    const state = generateState();
    const authURL = `https://gitee.com/oauth/authorize?client_id=${GITEE_CLIENT_ID}&redirect_uri=${encodeURIComponent(GITEE_REDIRECT_URI)}&response_type=code&state=${state}`;
    res.json({ authURL });
});

// Gitee回调处理
router.get('/gitee/callback', async (req, res) => {
    try {
        const { code, state } = req.query;
        // 获取access_token
        const tokenResponse = await axios.post('https://gitee.com/oauth/token', {
            client_id: GITEE_CLIENT_ID,
            client_secret: GITEE_CLIENT_SECRET,
            code,
            redirect_uri: GITEE_REDIRECT_URI,
            grant_type: 'authorization_code'
        });
        // 获取用户信息
        const userResponse = await axios.get('https://gitee.com/api/v5/user', {
            headers: { Authorization: `Bearer ${tokenResponse.data.access_token}` }
        });
        // 处理用户信息
        const giteeUser = userResponse.data;
        let user = await User.findOne({ giteeId: giteeUser.id.toString() });
        if (!user) {
            // 检查用户名是否已存在
            let username = giteeUser.login;
            let counter = 1;
            while (await User.findOne({ username })) {
                username = `${giteeUser.login}_${counter}`;
                counter++;
            }
            // 创建新用户
            user = new User({
                username: username,
                giteeId: giteeUser.id.toString(),
                avatar: giteeUser.avatar_url || 'https://tse4-mm.cn.bing.net/th/id/OIP-C.V-0gtFJqCf_iAWBxMd874AAAAA?rs=1&pid=ImgDetMain',
                accessToken: tokenResponse.data.access_token
            });

            await user.save();
        } else {
            // 更新现有用户信息
            user.avatar = giteeUser.avatar_url || user.avatar;
            user.accessToken = tokenResponse.data.access_token;
            await user.save();
        }

        // 生成JWT
        const token = jwt.sign({ userId: user._id }, 'your_secret_key', { expiresIn: '1h' });
        const refreshToken = jwt.sign({ userId: user._id }, 'your_refresh_secret_key', { expiresIn: '7d' });
        res.json({ token, refreshToken, user });

    } catch (error) {
        console.error('Gitee登录失败:', error);
        res.status(200).json({ message: '第三方登录失败' });
    }
});

router.post('/login', async (req, res) => {
    try {
        const { username, password } = req.body;
        const user = await User.find({ username });

        if (user[0]) {
            // 建议将 refreshToken 存入数据库（演示只返回给客户端）
            const token = jwt.sign({ userId: user[0]._id }, 'your_secret_key', { expiresIn: '1h' });
            const refreshToken = jwt.sign({ userId: user[0]._id }, 'your_refresh_secret_key', { expiresIn: '7d' });
            // 安全建议：将 refreshToken 存入数据库（这里演示返回给客户端）
            // await User.updateOne({ _id: user[0]._id }, { refreshToken });
            // 更安全的做法：通过 HttpOnly Cookie 返回 refreshToken
            res.cookie('refreshToken', refreshToken, {
                httpOnly: true,
                secure: process.env.NODE_ENV === 'production',
                sameSite: 'strict',
                maxAge: 7 * 24 * 60 * 60 * 1000
            });

            // 更新数据库中的refreshToken
            await User.updateOne({ _id: user[0]._id }, { refreshToken });

            res.json({
                code: 200,
                data: user,
                message: '登录成功'
            });

        } else {
            return res.status(401).json({ message: '账号或密码错误' });
        }
    } catch (error) {
        console.error('登录处理错误:', error);
        return res.status(401).json({ message: '服务器内部错误' });
    }
});


router.post('/register', async (req, res, next) => {
    try {
        const { phone, password, username, email } = req.body;
        
        // 检查用户名唯一性
        const existingUsername = await User.findOne({ username });
        if (existingUsername) {
            return res.send({
                code: 409,
                message: '用户名已被占用'
            });
        }
        // console.log(existingUsername);
        
        // 检查手机号是否已注册
        const existingPhone = await User.findOne({ phone });
        if (existingPhone) {
            return res.send({
                code: 409,
                message: '该手机号已注册'
            })
        }
        if (email) {
            const existingEmail = await User.findOne({ email })
            if (existingEmail) {
                return res.send({
                    code: 409,
                    message: '该邮箱已注册'
                });
            }
            try {
                const transporter = nodemailer.createTransport({
                    host: 'smtp.qq.com',
                    port: 465,
                    secure: true,
                    auth: {
                        user: '3078437987@qq.com',
                        pass: 'zqizxknrqihldfeb'
                    }
                });
                const mailOptions = {
                    from: '系统通知 <3078437987@qq.com>',
                    to: email,
                    subject: '账户注册成功通知',
                    html: `
                    <div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; max-width: 600px; margin: 20px auto; padding: 30px; border: 1px solid #eaeaea;">
                        <h2 style="color: #1890ff; border-bottom: 2px solid #1890ff; padding-bottom: 10px;">注册成功通知</h2>
                        <p>您好，${username}：</p>
                        <p style="line-height: 1.6;">感谢您注册协同办公平台，您的账户已成功创建。请妥善保管您的登录信息，如有任何问题请联系平台管理员。</p>
                        <div style="margin-top: 30px; color: #666; font-size: 0.9em;">
                            <p>注册时间：${new Date().toLocaleString()}</p>
                            <p>此邮件为系统自动发送，请勿直接回复。</p>
                        </div>
                    </div>
                    `,
                    text: `账户注册成功通知

                        您好 ${username}：

                        感谢您注册协同办公平台，您的账户已成功创建。
                        注册时间：${new Date().toLocaleString()}

                        请妥善保管您的登录信息，如有任何问题请联系平台管理员。

                        此邮件为系统自动发送，请勿直接回复。`
                };

                await transporter.sendMail(mailOptions);
                // res.json({ code: 200, message: '邮件发送成功' });
                const hashedPassword = await bcrypt.hash(password, 10);
                
                User.create({
                    username,
                    phone,
                    password: hashedPassword,
                    email
                })
                return res.send({
                    code: 200,
                    message: '注册成功'
                })
            } catch (error) {
                console.error('邮件发送失败:', error);
                res.status(500).json({
                    code: -1,
                    message: '邮件发送失败',
                    error: error.message
                });
            }
        }

        // 密码加密
        const hashedPassword = await bcrypt.hash(password, 10);
        // 创建新用户时添加username和avatar
       
        User.create({
            username,
            phone,
            password: hashedPassword,
        })
        return res.send({
            code: 200,
            message: '注册成功'
        })
    } catch (err) {
        console.log(err);
        res.send({
            code: -1,
            message: '注册失败'
        })
        
    }
});
// 新增 refreshToken 路由
router.post('/refresh-token', async (req, res) => {
    const { refreshToken } = req.body;
    if (!refreshToken) {
        return res.status(401).json({ message: '需要提供刷新令牌' });
    }
    try {
        // 验证 refreshToken（注意使用 refreshToken 的密钥）
        const decoded = jwt.verify(refreshToken, 'your_refresh_secret_key');
        // 检查用户是否存在
        const user = await User.findById(decoded.userId);
        if (!user) return res.status(404).json({ message: '用户不存在' });
        // 生成新的 access token（短效）
        const newToken = jwt.sign(
            { userId: user._id },
            'your_secret_key',
            { expiresIn: '1h' }
        );

        // 生成新的 refreshToken（可选，根据业务需求）
        const newRefreshToken = jwt.sign(
            { userId: user._id },
            'your_refresh_secret_key',
            { expiresIn: '7d' }
        );

        res.json({
            token: newToken,
            refreshToken: newRefreshToken // 如果刷新refreshToken需要返回
        });
    } catch (error) {
        if (error.name === 'TokenExpiredError') {
            return res.status(401).json({ message: '刷新令牌已过期，请重新登录' });
        }
        res.status(403).json({ message: '无效的刷新令牌' });
    }
});
router.get('/user', async (req, res) => {
    User.find().then(data=>{
        res.send({
            code: 200,
            data
        })
    })
})
// 定义验证 JWT 令牌的中间件
const verifyToken = (req, res, next) => {
    const token = req.headers['authorization'];
    if (!token) {
        return res.status(403).json({ message: '请登录后再试' });
    }

    jwt.verify(token, 'your_secret_key', async (err, decoded) => {
        if (err) {
            // Token 过期时返回特定状态码
            if (err.name === 'TokenExpiredError') {
                return res.status(401).json({
                    code: 'TOKEN_EXPIRED',
                    message: '令牌已过期'
                });
            }
            return res.status(403).json({ message: '请登录后再试' });
        }
        req.userId = decoded.userId;
        next();
    });
};

// 定义检查用户是否具有指定权限的中间件生成函数
const checkPermission = (permissionName) => {
    return async (req, res, next) => {
        try {
            // 根据用户 ID 从用户角色关联表中查找该用户关联的所有角色
            const userRoles = await UserRole.find({ user_id: req.userId }).populate('role_id');
            const roleIds = userRoles.map(userRole => userRole.role_id);

            // 根据角色 ID 从角色权限关联表中查找这些角色关联的所有权限id
            const rolePermissions = await RolePermission.find({ role_id: { $in: roleIds } }).populate('permission_id');

            // 提取用户关联的所有权限列表
            const userPermissions = await Permission.find({ _id: { $in: rolePermissions.map(rolePermission => rolePermission.permission_id) } })
            const userPermissionsNames = userPermissions.map(permission => permission.permission_name);
            // 检查用户是否具有指定的权限
            if (userPermissionsNames.includes(permissionName)) {
                // 如果具有指定权限，调用 next 函数，将请求传递给下一个中间件或路由处理函数
                next();
            } else {
                // 如果不具有指定权限，返回 403 状态码和错误信息
                res.status(403).json({ message: '您不具有该权限' });
            }
        } catch (error) {
            // 如果出现错误，返回 500 状态码和错误信息
            console.log(error);

            res.status(500).json({ message: '出现未知错误' }); m
        }
    };
};

router.post('/afsCheck', async (req, res) => {
    // 修改参数接收方式，匹配前端发送的 captchaVerifyParam
    const { captchaVerifyParam } = req.body;
    console.log(captchaVerifyParam);

    try {
        const client = createAFSClient();
        const params = {
            SessionId: captchaVerifyParam.sessionId,
            Sig: captchaVerifyParam.sig,
            Token: captchaVerifyParam.token,
            Scene: captchaVerifyParam.scene || "148ip69a" // 保持与前端 SceneId 一致
        };
        console.log(params);

        const result = await client.authenticateSig(params);
        console.log(result.body.code);

        // 调整响应格式匹配前端预期
        if (result.body.code == 900) {
            res.json({
                code: 200,  // 
                msg: '人机验证通过',
                data: result
            });
        } else {
            res.status(403).json({
                code: 403,  // 状态码改为 403
                msg: '人机验证未通过'
            });
        }
    } catch (error) {
        console.error('人机验证失败:', error);
        res.status(500).json({
            code: 500,  // 状态码改为 500
            msg: '验证服务异常'
        });
    }
});

// 登出用户登出时清除 refreshToken
router.post('/logout', verifyToken, async (req, res) => {
    await User.updateOne(
        { _id: req.userId },
        { $unset: { refreshToken: 1 } }
    );
    res.clearCookie('refreshToken');
    res.json({ message: '登出成功' });
});

// 发送验证码接口
router.post('/sendVerificationCode', async (req, res) => {
    const { phone } = req.body;
    console.log(phone)
    try {
        // 生成验证码
        const verificationCode = generateVerificationCode();
        // 模拟发送验证码到手机，实际使用时可调用第三方短信服务
        let smsClient = new SMSClient({
            accessKeyId: 'LTAI5tGvYcwsi9seeFzW3UVY',  //accessKeyId 前面提到要准备的
            secretAccessKey: 'dXVDsN8HZWfZfTiMqvoIpu4zGWnpTm'  //secretAccessKey 前面提到要准备的
        });
        console.log(`发送验证码 ${verificationCode} 到手机 ${phone}`);

        // 将验证码存入数据库，设置有效期（这里简单假设有效期为 5 分钟）
        const expirationTime = new Date(Date.now() + 5 * 60 * 1000);
        await VerificationCode.findOneAndUpdate(
            { phone },
            { code: verificationCode, expirationTime },
            { upsert: true }
        );
        smsClient.sendSMS({
            PhoneNumbers: phone,
            SignName: "璐琦佳慧", //签名名称 前面提到要准备的
            TemplateCode: "SMS_474880856", //模版CODE  前面提到要准备的
            TemplateParam: `{"code":"${verificationCode}"}`,  // 短信模板变量对应的实际值，JSON格式
        }).then(result => {
            console.log("result", result)
            let { Code } = result;
            if (Code == 'OK') {
                res.json({
                    code: 0,
                    msg: 'success',
                    sms: verificationCode
                })
                console.log(result)
            }
        }).catch(err => {
            console.log(err);
            res.json({
                code: 1,
                msg: 'fail: ' + err.data.Message
            })
        })
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: '验证码发送失败' });
    }
});

// 通过手机号验证码登录接口
router.post('/loginByPhone', async (req, res) => {
    const { phone, verificationCode } = req.body;
    try {
        // 从数据库中获取验证码信息
        const codeDoc = await VerificationCode.findOne({
            phone,
            code: verificationCode,
            expirationTime: { $gt: new Date() }
        });

        if (!codeDoc) {
            return res.status(401).json({ message: '手机号码或验证码错误' });
        }

        // 验证通过，生成 JWT 令牌
        const user = { phone };
        const token = jwt.sign(user, 'your_secret_key', { expiresIn: '1h' });
        const refreshToken = jwt.sign(user, 'your_refresh_secret_key', { expiresIn: '7d' });

        // 从数据库中获取用户名
        const userDoc = await User.findOne({ phone });
        const username = userDoc ? userDoc.username : null;

        res.status(200).json({ token, refreshToken, username });
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: '登录失败，请稍后重试' });
    }
});

module.exports = router;
